/*
 * Copyright 2010-2011 Sanjay Dwivedi.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.isdinvestments.ui.richgui.vaadin.cam;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import com.isdinvestments.ui.richgui.vaadin.common.fields.AddressField;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.DefaultFieldFactory;
import com.vaadin.ui.Field;
import com.vaadin.ui.Form;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.SplitPanel;
import com.vaadin.ui.Table;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.Button.ClickEvent;

/**
 * Main Customer view for Customer Account Management Web interface.
 * It depends on <code>CustomerPM</code>, the presentation model for the customer view.
 * All UI logic and behavior is in <code>CustomerPM</code>.'
 * 
 * @author Sanjay Dwivedi
 * @since 1.0
 *
 */
public class CustomerView {
	@Autowired
	private CustomerPM customerPresentationModel;
	private Window mainWindow;

	private static String[] visibleCols = new String[] { "id", "name", "taxId" };

	private Table customerTable = new Table();
	private Form customerForm = new Form();
	private HorizontalLayout bottomLeftCorner = new HorizontalLayout();
	private Button customerRemovalButton;

	public CustomerView() {
	}
	
	public Window getMainWindow() {
		return mainWindow;
	}
	
	public void init() {
		initLayout();
		initCustomerAddRemoveButtons();
		initCustomerTable();
		initFilteringControls();
	}

	private void initLayout() {
		SplitPanel splitPanel = new SplitPanel(
				SplitPanel.ORIENTATION_HORIZONTAL);
		mainWindow = new Window("ISD Investments - Intelligent Smart Financial Decisions", splitPanel);
		VerticalLayout left = new VerticalLayout();
		left.setSizeFull();
		left.addComponent(customerTable);
		customerTable.setSizeFull();
		left.setExpandRatio(customerTable, 1);
		splitPanel.addComponent(left);
		splitPanel.addComponent(customerForm);
		customerForm.setSizeFull();
		customerForm.getLayout().setMargin(true);
		customerForm.setImmediate(true);
		customerForm.setWriteThrough(true);
		customerForm.setFormFieldFactory(new CustomerFieldFactory());
//        List<String> visibleProperties = new ArrayList<String>();
//        visibleProperties.add("id");
//        visibleProperties.add("name");
//        visibleProperties.add("taxId");
//        visibleProperties.add("customerType");
//        visibleProperties.add("address");
//        visibleProperties.add("accounts");
//        customerForm.setVisibleItemProperties(visibleProperties);
		bottomLeftCorner.setWidth("100%");
		left.addComponent(bottomLeftCorner);
	}

	private void initCustomerAddRemoveButtons() {
		// New item button
		bottomLeftCorner.addComponent(new Button("+",
				new Button.ClickListener() {
					public void buttonClick(ClickEvent event) {
						Object id = customerTable.addItem();
						customerTable.setValue(id);
					}
				}));

		// Remove item button
		customerRemovalButton = new Button("-", new Button.ClickListener() {
			public void buttonClick(ClickEvent event) {
				customerTable.removeItem(customerTable.getValue());
				customerTable.select(null);
			}
		});
		customerRemovalButton.setVisible(false);
		bottomLeftCorner.addComponent(customerRemovalButton);
	}

	private String[] initCustomerTable() {
		customerTable.setContainerDataSource(customerPresentationModel.getCustomerList());
		customerTable.setColumnHeader("id", "Customer ID");
		customerTable.setColumnHeader("name", "Customer Name");
		customerTable.setColumnHeader("taxId", "Customer Tax ID");
		customerTable.setVisibleColumns(visibleCols);
		customerTable.setSelectable(true);
		customerTable.setImmediate(true);
		customerTable.addListener(new Property.ValueChangeListener() {
			public void valueChange(ValueChangeEvent event) {
				Object id = customerTable.getValue();
		        List<String> visibleProperties = new ArrayList<String>();
		        visibleProperties.add("id");
		        visibleProperties.add("name");
		        visibleProperties.add("taxId");
		        visibleProperties.add("customerType");
		        visibleProperties.add("address");
		        visibleProperties.add("accounts");
				customerForm.setItemDataSource(id == null ? null : customerTable
						.getItem(id), visibleProperties);
				customerRemovalButton.setVisible(id != null);
			}
		});
		return visibleCols;
	}

	private void initFilteringControls() {
		for (final String pn : visibleCols) {
			final TextField sf = new TextField();
			bottomLeftCorner.addComponent(sf);
			sf.setWidth("100%");
			sf.setInputPrompt(pn);
			sf.setImmediate(true);
			bottomLeftCorner.setExpandRatio(sf, 1);
			sf.addListener(new Property.ValueChangeListener() {
				public void valueChange(ValueChangeEvent event) {
					customerPresentationModel.removeCustomerListFilters(pn);
					if (sf.toString().length() > 0 && !pn.equals(sf.toString())) {
						customerPresentationModel.addCustomerListFilter(pn, sf.toString(),
								true, false);
					}
					getMainWindow().showNotification(
							"" + customerPresentationModel.getCustomerListSize() + " matches found");
				}
			});
		}
	}
	
    /**
     * Field factory for CustomerView form
     */
    private class CustomerFieldFactory extends DefaultFieldFactory {
		private static final long serialVersionUID = 6880954356570686447L;
		// reuse the address field - required by EmbeddedForm
        private AddressField addressField;

        @Override
        public Field createField(Item item, Object propertyId, Component uiContext) {
            Field f = super.createField(item, propertyId, uiContext);
            if ("address".equals(propertyId)) {
                // create a custom field for the Address object
                if (addressField == null) {
                    Form form = (uiContext instanceof Form) ? (Form) uiContext
                            : null;
                    addressField = new AddressField(form);
                }
                f = addressField;
            }
            return f;
        }
    }
}
